package mk.jug.academy.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import mk.jug.academy.model.Course;
import mk.jug.academy.model.Lecturer;
import mk.jug.academy.model.Page;
import mk.jug.academy.model.status.CourseStatus;

import org.springframework.stereotype.Repository;


/**
 * DAO for {@link Course}.
 * 
 * @author Ice.Penov
 */
@Repository
public class CourseDAO extends GenericDAO<Course> {
	
	/**
	 * Fetches all Courses, regardless of their status,
	 * in a paged manner, considering the start and end
	 * boundaries.
	 */
	public Page<Course> findAll(final int start, final int end) {
		return new QueryEMContext<Page<Course>>() {
			@Override @SuppressWarnings("unchecked")
			public Page<Course> query(EntityManager em) {
				Query query = em.createQuery("Select from Course c order by c.modified desc");
				query.setFirstResult(start);
				query.setMaxResults(end);
				List<Course> list = query.getResultList();
				query = em.createQuery("Select count(c.id) from Course c");
				return new Page<Course>(initialize(list), (Integer) query.getSingleResult());
			}
		}.result();
	}
	
	/**
	 * Fetches the courses with the given status, in a paged
	 * manner, considering the start and end boundaries.
	 */
	public Page<Course> findByStatus(final CourseStatus status, final int start, final int end) {
		return new QueryEMContext<Page<Course>>() {
			@Override @SuppressWarnings("unchecked")
			public Page<Course> query(EntityManager em) {
				Query query = em.createQuery("Select c from mk.jug.academy.model.Course c where c.status = :status order by c.modified desc");
				query.setParameter("status", status);
				query.setFirstResult(start);
				query.setMaxResults(end);
				List<Course> list = query.getResultList();
				query = em.createQuery("Select count(c.id) from Course c where c.status = :status");
				query.setParameter("status", status);
				return new Page<Course>(initialize(list), (Integer) query.getSingleResult());
			}
		}.result();
	}
	
	/**
	 * Fetches the {@link Course}s for the given {@link Lecturer}.
	 * 
	 * @param id the lecturer ID. 
	 */
	public List<Course> findByLecturer(final Long id) {
		return new QueryEMContext<List<Course>>() {
			@Override @SuppressWarnings("unchecked")			
			public List<Course> query(EntityManager em) {
				Query query = em.createQuery("Select c from mk.jug.academy.model.Course c where c.lecturerID = :lecturerID"); 
				query.setParameter("lecturerID", id);
				List<Course> list = query.getResultList();
				return initialize(list);
			}
		}.result();
	}
	
	/**
	 * Fetches the <code>Courses</code> with the given status. 
	 */
	public List<Course> findByStatus(final CourseStatus status) {
		return new QueryEMContext<List<Course>> () {
			@Override @SuppressWarnings("unchecked")
			public List<Course> query(EntityManager em) {
				Query query = em.createQuery("Select c from mk.jug.academy.model.Course c where c.status = :status");
				query.setParameter("status", status);
				return initialize(query.getResultList());
			}
		}.result();
	}	
		
}